package com.yz.design.concurrents;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @ClassName ListDistrict
 * @Description 1.嵌套循环获取，
 * 2.contains()重写 equals()方法
 * 3.使用stream().distinct() 重写 hashCode（）和equals（）
 * @Author 广长
 * @Date 2020/8/11
 * @Version V1.0
 **/
public class ListDistinct {
    public static void main(String[] args) {
        List<PenBean> penBeanList = new ArrayList<>();
        penBeanList.add(new PenBean("铅笔", "black"));
        penBeanList.add(new PenBean("铅笔", "white"));
        penBeanList.add(new PenBean("铅笔", "black"));
        penBeanList.add(new PenBean("中性笔", "white"));
        penBeanList.add(new PenBean("中性笔", "white"));
        // 2.contains()重写equals()方法
        List<PenBean> newPenBeanList1 = new ArrayList<>();
        for (PenBean penBean : penBeanList) {
            if (!newPenBeanList1.contains(penBean)) {
                newPenBeanList1.add(penBean);
            }
        }
        System.out.println(newPenBeanList1);
        // 3. 使用stream().distinct()  重写 hashCode（）和equals（）
        System.out.println(penBeanList.stream().distinct().collect(Collectors.toList()));
        // 4. distinctByKey 根据某个字段
        penBeanList.stream().filter(distinctByKey(PenBean::getType)).map(PenBean::getType).forEach(System.out::println);
        // 5. hashSet  重写 hashCode（）和 equals（）
        Set<PenBean> hashSet = new HashSet<>(penBeanList);
        System.out.println(hashSet);


    }

    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        // 分段式锁，线程安全，非阻塞的，局部锁住，bi
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}

